package ddd2;

import java.io.PrintWriter;
import java.time.Duration;
import java.time.LocalDateTime;
import java.util.Random;
import java.util.Scanner;

public class MoveNumber {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int[][] nums = {{1,2,3},{4,5,6},{7,0,8}};//按下d通关
        /* --目标：
        * 1  2  3
        * 4  5  6
        * 7  8  0
         */
        shuffle2DArray(nums);  // 打乱原数组
        LocalDateTime time = LocalDateTime.now();
        while(true) {
            PrintNum(nums);
            System.out.print("Enter w/a/s/d ");
            char input = sc.nextLine().charAt(0);
            if(input == 'w') {
                W(nums);
            }
            else if(input == 's') {
                S(nums);
            }
            else if(input == 'd') {
                D(nums);
            }
            else if(input == 'a') {
                A(nums);
            }
            if(isTrue(nums)) {
                System.out.println("Your move is correct");
                System.out.println("用时："+ Duration.between(time, LocalDateTime.now()).getSeconds() + " seconds");
                break;
            }
        }


    }
    public static int getX(int[][] nums) {
        for (int i = 0; i < nums.length; i++) {
            for (int j = 0; j < nums[i].length; j++) {
                if(nums[i][j] == 0){
                    return i;
                }
            }
        }
        return 100;
    }

    public static int getY(int[][] nums) {
        for (int i = 0; i < nums.length; i++) {
            for (int j = 0; j < nums[i].length; j++) {
                if(nums[i][j] == 0){
                    return j;
                }
            }
        }
        return 100;
    }
    public static void move(int[][] nums, int i, int j) {
        int x = getX(nums);
        int y = getY(nums);
        int temp = nums[i][j];
        nums[i][j] = 0;
        nums[x][y] = temp;
    }
    public static void W(int[][] nums) {
        if(getX(nums)==100){return;}
        if(getX(nums)==0){System.out.println("无法移动");return;}
        move(nums,getX(nums)-1,getY(nums));
    }

    public static void A(int[][] nums) {
        if(getY(nums)==100){return;}
        if(getY(nums)==0){System.out.println("无法移动");return;}
        move(nums,getX(nums),getY(nums)-1);
    }

    public static void S(int[][] nums) {
        if(getX(nums)==100){return;}
        if(getX(nums)==2){System.out.println("无法移动");return;}
        move(nums,getX(nums)+1,getY(nums));
    }

    public static void D(int[][] nums) {
        if(getY(nums)==100){return;}
        if(getY(nums)==2){System.out.println("无法移动");return;}
        move(nums,getX(nums),getY(nums)+1);
    }
    public static void PrintNum(int[][] nums) {
        System.out.println("目前棋盘如下");
        for (int i = 0; i < nums.length; i++) {
            for (int j = 0; j < nums[i].length; j++) {
                System.out.print(nums[i][j] + " | ");
            }
            System.out.println();
        }
    }
    public static void shuffle2DArray(int[][] array) {
        int rows = array.length;
        int cols = array[0].length;
        Random rand = new Random();
        int[] flat = new int[rows * cols];
        int index = 0;
        for (int[] row : array) {
            for (int val : row) {
                flat[index++] = val;
            }
        }
        for (int i = flat.length - 1; i > 0; i--) {
            int j = rand.nextInt(i + 1);
            int temp = flat[i];
            flat[i] = flat[j];
            flat[j] = temp;
        }
        index = 0;
        for (int i = 0; i < rows; i++) {
            for (int j = 0; j < cols; j++) {
                array[i][j] = flat[index++];
            }
        }
    }
    public static boolean isTrue(int[][] nums) {
        int[][] NewNums = {{1,2,3},{4,5,6},{7,8,0}};
        for (int i = 0; i < NewNums.length; i++) {
            for (int j = 0; j < NewNums[i].length; j++) {
                if (NewNums[i][j] != nums[i][j]){
                    return false;
                }
            }
        }
        return true;
    }
}
